from flask import jsonify, request
from extensions import db
from models.version import Version
from models.project import Project
from services.fastlane import FastlaneService
from services.app_store_connect import AppStoreConnectService
from . import api
from .errors import bad_request, not_found
from tasks.version_tasks import process_version
from utils.logger import logger, log_api_call

@api.route('/versions', methods=['GET'])
@log_api_call
def get_versions():
    """获取所有版本列表"""
    logger.info("获取版本列表")
    versions = Version.query.all()
    logger.info(f"找到 {len(versions)} 个版本")
    return jsonify([version.to_dict() for version in versions])

@api.route('/versions/<int:id>', methods=['GET'])
@log_api_call
def get_version(id):
    """获取单个版本详情"""
    logger.info(f"获取版本详情: {id}")
    version = Version.query.get_or_404(id)
    logger.info(f"找到版本: {version.version_number} (项目ID: {version.project_id})")
    return jsonify(version.to_dict())

@api.route('/versions', methods=['POST'])
@log_api_call
def create_version():
    """创建新版本"""
    logger.info("开始处理创建版本请求")
    
    if not request.is_json:
        logger.warning("请求Content-Type不是application/json")
        return bad_request('Content-Type must be application/json')
    
    try:
        data = request.get_json()
    except Exception as e:
        logger.error(f"解析JSON数据失败: {str(e)}")
        return bad_request('Invalid JSON data')
    
    if not data:
        logger.warning("请求中没有提供数据")
        return bad_request('No data provided')
    
    required_fields = ['project_id', 'version_number']
    
    # 验证必填字段
    for field in required_fields:
        if field not in data:
            logger.warning(f"缺少必填字段: {field}")
            return bad_request(f'Missing required field: {field}')
        if not data[field]:
            logger.warning(f"字段值为空: {field}")
            return bad_request(f'Field cannot be empty: {field}')
    
    # 验证项目是否存在
    project = Project.query.get(data['project_id'])
    if not project:
        logger.warning(f"项目不存在: {data['project_id']}")
        return not_found('Project not found')
    
    # 验证版本号是否已存在
    if Version.query.filter_by(
        project_id=data['project_id'],
        version_number=data['version_number']
    ).first():
        logger.warning(f"版本号已存在: {data['version_number']} (项目ID: {data['project_id']})")
        return bad_request('Version number already exists for this project')
    
    try:
        logger.info("开始创建版本")
        version = Version()
        version.from_dict(data, partial=False)
        db.session.add(version)
        db.session.commit()
        logger.info(f"版本创建成功: {version.id}")
        
        # 触发异步任务
        logger.info(f"触发版本处理任务: {version.id}")
        task = process_version.delay(version.id)
        logger.info(f"任务已创建: {task.id}")
        
        response = jsonify({
            'message': 'Version creation started',
            'version': version.to_dict(),
            'task_id': task.id
        })
        response.status_code = 201
        return response
    except ValueError as e:
        logger.error(f"版本创建失败 - 验证错误: {str(e)}")
        return bad_request(str(e))
    except Exception as e:
        logger.error(f"版本创建失败 - 未知错误: {str(e)}", exc_info=True)
        db.session.rollback()
        return bad_request(f'Error creating version: {str(e)}')

@api.route('/versions/<int:id>', methods=['PUT'])
@log_api_call
def update_version(id):
    """更新版本信息"""
    logger.info(f"开始处理更新版本请求: {id}")
    
    version = Version.query.get_or_404(id)
    logger.info(f"找到版本: {version.version_number} (项目ID: {version.project_id})")
    
    if not request.is_json:
        logger.warning("请求Content-Type不是application/json")
        return bad_request('Content-Type must be application/json')
    
    try:
        data = request.get_json()
    except Exception as e:
        logger.error(f"解析JSON数据失败: {str(e)}")
        return bad_request('Invalid JSON data')
    
    if not data:
        logger.warning("请求中没有提供数据")
        return bad_request('No data provided')
    
    # 不允许更改项目ID和版本号
    if 'project_id' in data or 'version_number' in data:
        logger.warning("尝试修改project_id或version_number")
        return bad_request('Cannot modify project_id or version_number')
    
    try:
        logger.info("开始更新版本")
        version.from_dict(data, partial=True)
        db.session.commit()
        logger.info(f"版本更新成功: {version.id}")
        return jsonify(version.to_dict())
    except ValueError as e:
        logger.error(f"版本更新失败 - 验证错误: {str(e)}")
        return bad_request(str(e))
    except Exception as e:
        logger.error(f"版本更新失败 - 未知错误: {str(e)}", exc_info=True)
        db.session.rollback()
        return bad_request(f'Error updating version: {str(e)}')

@api.route('/versions/<int:id>', methods=['DELETE'])
@log_api_call
def delete_version(id):
    """删除版本"""
    logger.info(f"开始处理删除版本请求: {id}")
    
    version = Version.query.get_or_404(id)
    logger.info(f"找到版本: {version.version_number} (项目ID: {version.project_id})")
    
    try:
        logger.info("开始删除版本")
        db.session.delete(version)
        db.session.commit()
        logger.info(f"版本删除成功: {id}")
        return '', 204
    except Exception as e:
        logger.error(f"版本删除失败: {str(e)}", exc_info=True)
        db.session.rollback()
        return bad_request(f'Error deleting version: {str(e)}')

@api.route('/versions/<int:id>/status', methods=['GET'])
@log_api_call
def get_version_status(id):
    """获取版本状态"""
    logger.info(f"获取版本状态: {id}")
    
    version = Version.query.get_or_404(id)
    logger.info(f"找到版本: {version.version_number} (项目ID: {version.project_id})")
    logger.info(f"状态: {version.status}, 下载状态: {version.download_status}, 上传状态: {version.upload_status}")
    
    return jsonify({
        'id': version.id,
        'status': version.status,
        'download_status': version.download_status,
        'upload_status': version.upload_status,
        'error_message': version.error_message,
        'created_at': version.created_at.isoformat() if version.created_at else None,
        'completed_at': version.completed_at.isoformat() if version.completed_at else None
    })
